/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Auto;

import RTPower.MD5Util;
import RTPower.RTHttp;
import RTPower.RTdate;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.awt.Image;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Random;
import javax.swing.ImageIcon;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.springframework.web.util.HtmlUtils;
import panel.FriendsPanel;
import weixin.AdminMain;
import weixin.AllLoginMain;

/**
 * 微信自动主类
 * <br>全部方法在里面,
 * <br>每次实例就是一个新的微信
 *
 * @author jerry
 */
public class WeiXinAuto {

    /**
     * 当前微信的cookies记录
     */
    public HashMap WXCookies = new HashMap();

    /**
     * 当前微信的个人信息记录
     * <br>包括UUID 头像
     */
    public HashMap MyInfo = new HashMap();

    /**
     * 朋友列表信息记录
     */
    public JsonArray AllfriendsList = new JsonArray();

    /**
     * 最近联系的朋友列表
     * <br>ArrayList 方便倒序 从最新的开始排列,
     * <br>仅仅记录最新的联系用户的username
     */
    public ArrayList AllLastCallFriends = new ArrayList();

    /**
     * 组信息记录
     */
    public HashMap GroupList = new HashMap();

    /**
     * 扫码监听状态
     */
    public boolean login_scan_status = true;

    /**
     * 循环值守的线程的状态
     */
    public boolean ThreadStatus = false;

    /**
     * 心跳线程
     */
    public Thread HeartJumpThread;

    /**
     * 记录下自己账号的ImageIcon 方柏霓使用
     */
    public Image MyFaceImage;

    /**
     * 存储所有最新接收到的一次新消息
     * <br>这里存入以后,如果没有读取,则是一直存在,
     * <br>再有新消息进入,继续累加
     * <br>真正读取显示后,才从这里消失.
     */
    public JsonObject AllNewMsg = new JsonObject();

    /**
     * 此处存放所有用户的老聊天记录
     * <br>格式为 [用户名][时间][消息];
     */
    public JsonObject AllOldMsg = new JsonObject();

    /**
     * 此账号的username id,在初始化微信的时候赋予
     * <br>方便使用
     */
    public String AdminUserName = "";

    /**
     * 初始化就开始运行
     */
    public WeiXinAuto() {
        //初始化的时候就获取UUID
        GetUUID();
    }

    /**
     * 第一步获取UUID
     * <br>并且记录,用来获得二维码使用
     */
    private void GetUUID() {

        System.setProperty("jsse.enableSNIExtension", "false");
        //请求http获得uuid
        String set_url = "https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb"
                + "&fun=new&lang=zh_CN&_=" + RTdate.GetNowStemp();
        RTHttp rhttp = new RTHttp(set_url);
        String result = rhttp.Get();
        rhttp.close();
        //解析内容,判断是否状态正常,以及获得UUID并记录
        //检查200;是否存在,不存在则终止
        if (!result.contains("200;")) {
            System.err.println("获取UUID返回状态出错:" + result);
            return;
        }
        //获得切割数据 得到UUID
        //截取其中的UUID
        String UUID = result.split("\"")[1];

        //记录下这个UUID
        MyInfo.put("LoginUUID", UUID);
        System.err.println("获得UUID:" + UUID);
    }

    /**
     * 获得二维码图片
     * <br>获取数据并返回byte[]
     *
     * @return 图片数据
     */
    public byte[] GetImage() {

        //根据UUID获取验证码
        String set_url = "https://login.weixin.qq.com/qrcode/"
                + MyInfo.get("LoginUUID");
        RTHttp rhttp = new RTHttp(set_url);
        byte[] result_image = rhttp.GetImage();
        rhttp.close();
        return result_image;
    }

    /**
     * 持续检查是否扫码以及点击登录
     * <br>并更新扫码图片的显示
     *
     * @param login_main
     */
    public void ScanLoginStatus(AllLoginMain login_main) {

        //设置tip默认是1 就是还没有扫码
        MyInfo.put("login_tip", "1");
        //进行轮训每2秒
        new Thread(() -> {

            while (login_scan_status) {

                //如果返回false 则终止线程
                if (!GetScanStatus(login_main)) {
                    login_scan_status = false;
                    //关闭二维码页面
                    login_main.dispose();
                    System.err.println("关闭微信二维码界面.");
                }
                try {
                    Thread.sleep(2000);
                    System.err.println("状态:循环中......");
                } catch (InterruptedException ex) {
                    System.err.println("出错:循环检查扫码状态");
                }
            }
        }).start();
    }

    //=======================================================================
    /**
     * 检查扫码状态一次,获得状态码
     */
    private boolean GetScanStatus(AllLoginMain login_main) {
        if (!login_scan_status) {
            return false;
        }
        String set_url = "https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login"
                + "?loginicon=true&uuid=" + MyInfo.get("LoginUUID") + ""
                + "&tip=" + MyInfo.get("login_tip").toString() + "&_=" + RTdate.GetNowStemp();
        RTHttp rhttp = new RTHttp(set_url);
        String result = rhttp.Get();
        rhttp.close();

        System.err.println(set_url);
        //检查状态码
        //如果是201 则有头像返回,如果是200 有URL返回,如果是408则是登录超时了
        if (result.contains("408;")) {
            //登录超时,弹出提示关闭窗体,终止进程
            System.err.println("扫码超时408.....");
            return false;
        }

        //是201 就代表扫码了,记录头像
        if (result.contains("201;")) {

            String result_image = result.split("\'")[1];
            result_image = result_image.replace("data:img/jpg;base64,", "");
            System.err.println("扫码完毕,等待点击登录.....");
            //截取头像信息
            MyInfo.put("UserFaceImage", result_image);
//            System.err.println(result_image);
            byte[] use_byte = Base64.getDecoder().decode(result_image);
            //将图片解码,并显示给控件
            //改变图片大小

            login_main.erweima_image.setIcon(new ImageIcon(SetImageSize(new ImageIcon(use_byte), 200, 200)));
            login_main.login_text.setText("请手机上点击确认");

            MyInfo.put("login_tip", "0");
            return true;
        }

        //扫码并登录成功,记录下详细的url和cookies
        if (result.contains("200;")) {
            String result_url = result.split("\"")[1];
            System.err.println("扫码以及登录完成.....");
            System.err.println("获得URL:" + result_url);
            login_main.dispose();
            //获得cookies
            GetLoginInfo(result_url);
            return false;
        }

        //以上情况都不是就一直循环
        return true;
    }

    /**
     * 获取登录后其他必要步骤
     * <br>获得cookies,初始化,开启通知,执行心跳
     *
     * @param result_url
     */
    private void GetLoginInfo(String result_url) {

        //生成一个通用的did
        int radomInt = new Random().nextInt(99999);
        int radomInt2 = new Random().nextInt(99999);
        int radomInt3 = new Random().nextInt(99999);
        int radomInt4 = new Random().nextInt(99999);
        String devidString = radomInt + "" + radomInt2 + "" + radomInt3 + "" + radomInt4;
        MyInfo.put("DeviceID", "e" + devidString.substring(0, 15));

        GetCookies(result_url);
        //至此登录已经成功,先初始化一次,获得一些基本信息
        GetWeiXinInit();

        //如果在微信自动类里面已经有了这个账号id,则先清除这个id,防止一个账号重复
        if (AdminMain.AllWeiXinAutos.containsKey(WXCookies.get("wxuin").toString())) {
            ChangeShow.CloseOneWxAdmin(WXCookies.get("wxuin").toString());
        }
        //将这个实例赋予主控台的 实例列表,这里以wxuin作为key 这是微信号的id
        AdminMain.AllWeiXinAutos.put(WXCookies.get("wxuin").toString(), this);

        //增加账号显示在界面的第一栏
        ChangeShow.AddNewAdminFace(WXCookies.get("wxuin").toString());
        //激活刷新一次界面的账号列表显示

        //开启消息通知
        GetWeiXinStatusNotify();
        //获得微信联系人
        GetContact();

        //保持心跳,不断刷新消息检查
        ThreadStatus = true;
        HeartJump();
    }

    /**
     * 获得微信登录的cookies
     */
    private void GetCookies(String result_url) {
        RTHttp http = new RTHttp(result_url + "&fun=new&&version=v2");
        String cookies_webString = http.Get();//获得xml
        HashMap get_cookies = http.GetCookiesMap();
        http.close();
        //解析xml
        Document xml = Jsoup.parse(cookies_webString, "", Parser.xmlParser());

        //记录进cookieshash
        WXCookies.put("skey", xml.select("skey").text());
        WXCookies.put("wxsid", xml.select("wxsid").text());
        WXCookies.put("wxuin", xml.select("wxuin").text());
        WXCookies.put("pass_ticket", xml.select("pass_ticket").text());
        WXCookies.put("webwx_data_ticket", get_cookies.get("webwx_data_ticket").toString());
        //以上更新好了cookies,就说明登录成功
        System.err.println("微信获取cookies完毕.....");
        System.err.println("Skey:" + WXCookies.get("skey").toString());
    }

    /**
     * 根据本地文件信息进行直接登录
     *
     * @param wx_cookies
     * @param DeviceID
     * @param UserFaceImage
     */
    public void ScanFileAdminLogin(HashMap wx_cookies, String DeviceID, String UserFaceImage) {
        //传入并覆盖cookies 和info信息
        WXCookies = wx_cookies;
        MyInfo.put("DeviceID", DeviceID);
        MyInfo.put("UserFaceImage", UserFaceImage);
        //先初始化一次,获得一些基本信息
        GetWeiXinInit();
        //界面显示
        //将这个实例赋予主控台的 实例列表,这里以wxuin作为key 这是微信号的id
        AdminMain.AllWeiXinAutos.put(WXCookies.get("wxuin").toString(), this);

        //增加账号显示在界面的第一栏
        ChangeShow.AddNewAdminFace(WXCookies.get("wxuin").toString());
//开启消息通知
        if (!GetWeiXinStatusNotify()) {
            return;
        }
        //获得微信联系人
        GetContact();

        //保持心跳,不断刷新消息检查
        ThreadStatus = true;
        HeartJump();
    }

    /**
     * 微信初始化(初始化的时候已经获得了个人基本信息)
     */
    private void GetWeiXinInit() {
        //接着微信初始化
        RTHttp http2 = new RTHttp("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit");

        //准备post的jsonstring
        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", WXCookies.get("wxuin").toString());
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        JsonObject new_jsonob = new JsonObject();
        new_jsonob.add("BaseRequest", jsonob);
        String post_json_string = HashToJsonString(new_jsonob);

        http2.SetCookies(http2.MakeCookies(WXCookies));
        String formatString = http2.Post(post_json_string);//获得xml

        http2.close();
        //解析xml,其中最关键的Synckey 记录下来

        Gson json = new Gson();
        JsonObject new_json = json.fromJson(formatString, JsonObject.class);

        MyInfo.put("SyncKey", new_json.get("SyncKey"));
        MyInfo.put("User", new_json.get("User"));
        //加入最近的好友联系列表
        JsonArray ContactList = new_json.get("ContactList").getAsJsonArray();
        //同时也写出给All
        AllfriendsList = ContactList;

        //循环解析这里获得的是最近联系人,仅仅把用户名存储下来
        Iterator<JsonElement> iter = ContactList.iterator();

        while (iter.hasNext()) {
            JsonObject next = (JsonObject) iter.next();
            String user_name = next.get("UserName").getAsString();
            //把用户名加入数组,存在的就不加入
            if (!AllLastCallFriends.contains(user_name)) {
                AllLastCallFriends.add(user_name);
            }

        }
        //执行一次降序
        ArrayList new_all_last_call_friends = new ArrayList();
        ListIterator liter = AllLastCallFriends.listIterator(AllLastCallFriends.size());
        while (liter.hasPrevious()) {
            String next = liter.previous().toString();
            new_all_last_call_friends.add(next);
        }
        AllLastCallFriends = new_all_last_call_friends;

        System.err.println("微信初始化完毕.....");
    }

    /**
     * 开启微信状态通知
     */
    private boolean GetWeiXinStatusNotify() {
        RTHttp ohttp = new RTHttp("https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN&pass_ticket=" + WXCookies.get("pass_ticket"));
        JsonObject use_info = (JsonObject) MyInfo.get("User");
        AdminUserName = use_info.get("UserName").getAsString();
        //准备post的jsonstring
        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", WXCookies.get("wxuin").toString());
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        JsonObject new_jsonob = new JsonObject();
        new_jsonob.add("BaseRequest", jsonob);
        new_jsonob.addProperty("Code", 3);
        new_jsonob.addProperty("FromUserName", AdminUserName);
        new_jsonob.addProperty("ToUserName", AdminUserName);
        new_jsonob.addProperty("ClientMsgId", System.currentTimeMillis());
        String post_json_string = HashToJsonString(new_jsonob);

        ohttp.SetCookies(ohttp.MakeCookies(WXCookies));
        String s_webString = ohttp.Post(post_json_string);//获得xml
        ohttp.close();

        System.err.println("开启微信状态通知....");
        Gson us_gson = new Gson();
        JsonObject us_json = us_gson.fromJson(s_webString, JsonObject.class);
        JsonObject BaseResponse = us_json.getAsJsonObject("BaseResponse");
        String ret_text = BaseResponse.get("Ret").toString();
        if (!ret_text.equals("0")) {
            //同步出错则销毁自己
            ChangeShow.CloseOneWxAdmin(WXCookies.get("wxuin").toString());
            return false;
        }
        System.err.println(s_webString);
        return true;
    }

    /**
     * 获取微信联系人列表(使用新线程)
     */
    private void GetContact() {
        new Thread(() -> {
            String post_url = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact";

            JsonObject jsonob = new JsonObject();
            jsonob.addProperty("Uin", WXCookies.get("wxuin").toString());
            jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
            jsonob.addProperty("Skey", WXCookies.get("skey").toString());
            jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

            JsonObject new_jsonob = new JsonObject();
            new_jsonob.add("BaseRequest", jsonob);
            String post_json_string = HashToJsonString(new_jsonob);

            RTHttp rhttp = new RTHttp(post_url);
            rhttp.SetCookies(rhttp.MakeCookies(WXCookies));
            String result_string = rhttp.Post(post_json_string);
            rhttp.close();

            //更新之前获取的最近联系人列表
            Gson json = new Gson();
            JsonObject new_json = json.fromJson(result_string, JsonObject.class);
            //因为之前初始化的时候获得了最近联系人,这里要把之前的追加进这里
            JsonArray all_friends = new_json.get("MemberList").getAsJsonArray();
            //循环之前的,一个个加入
            Iterator<JsonElement> json_iter = AllfriendsList.iterator();
            while (json_iter.hasNext()) {
                JsonObject next = (JsonObject) json_iter.next();
                //只加入不存在的,并且@存在
                if (!all_friends.contains(next)) {
                    all_friends.add(next);
                }

            }
            AllfriendsList = all_friends.getAsJsonArray();

            System.err.println("正在刷新朋友列表");
            //刷新界面
            ChangeShow.ShowAllFriendsList(WXCookies.get("wxuin").toString());

            System.err.println("获取联系人信息完毕!");
//        System.err.println(result_string);
        }).start();

    }

    /**
     * 保持与服务器的心跳 循环线程执行
     */
    private void HeartJump() {

        HeartJumpThread = new Thread(() -> {
            while (ThreadStatus) {

                //只运行一个同步检测,如果有消息,则内部再执行获取消息
                GetSyncCheck();

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    System.err.println("心跳休眠失败...");
                }
            }
        });
        HeartJumpThread.start();
    }

    /**
     * 检查同步状态
     */
    private void GetSyncCheck() {

        String get_url = "";
        try {
            get_url = "https://webpush.wx2.qq.com/cgi-bin/mmwebwx-bin/synccheck"
                    + "?skey=" + URLEncoder.encode(WXCookies.get("skey").toString(), "UTF-8")
                    + "&r=" + System.currentTimeMillis()
                    + "&sid=" + URLEncoder.encode(WXCookies.get("wxsid").toString(), "UTF-8")
                    + "&uin=" + WXCookies.get("wxuin").toString()
                    + "&deviceid=" + MyInfo.get("DeviceID").toString()
                    + "&synckey=" + URLEncoder.encode(MakeSynckey(), "UTF-8")
                    + "&_=" + System.currentTimeMillis();
        } catch (UnsupportedEncodingException ex) {
            System.err.println("检查同步出错");
        }

        //这是一个长链接,加超时为60秒
        RTHttp http = new RTHttp(get_url) {
            @Override
            public void ChangeTimeOut() {
                TimeOut = 60000;
            }
        };

        http.SetCookies(http.MakeCookies(WXCookies));
        String result_string = http.Get();
        String show_cookies = http.GetCookies();

        http.close();

        System.err.println(WXCookies.get("wxuin").toString() + "同步结果:" + result_string);

        //过滤结果,得出2个参数,来判断是否要获取消息
        String[] new_json_string = result_string.split("\"");

        //得到2个参数,第一个不是0就说明断线了,第二个不是0就是有消息
        if (!new_json_string[1].equals("0")) {
            System.err.println("同步出错:" + new_json_string[1]);
            //同步出错则销毁自己
            ChangeShow.CloseOneWxAdmin(WXCookies.get("wxuin").toString());
        }

        //如果消息通知不是0就是有消息,则进行同步一下消息
        if (!new_json_string[3].equals("0")) {
            GetSyncMsg();
        }

    }

    /**
     * 执行一次获取最新消息的检查
     *
     */
    private void GetSyncMsg() {

        String get_url = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync"
                + "?sid=" + WXCookies.get("wxsid").toString() + ""
                + "&r=" + System.currentTimeMillis();

        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", WXCookies.get("wxuin").toString());
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        JsonObject new_jsonob = new JsonObject();
        new_jsonob.add("BaseRequest", jsonob);
        new_jsonob.add("SyncKey", (JsonObject) MyInfo.get("SyncKey"));

        String post_json_string = HashToJsonString(new_jsonob);

        //值守心跳
        RTHttp http = new RTHttp(get_url);

        http.SetCookies(http.MakeCookies(WXCookies));
        String sny_webString = http.Post(post_json_string);
        String show_cookies = http.GetCookies();
        http.close();
        //有新的SyncKey就要更新
        Gson gson = new Gson();
        JsonObject usjson = gson.fromJson(sny_webString, JsonObject.class);
        MyInfo.put("SyncKey", usjson.get("SyncKey"));
//        System.err.println(get_url);
//        System.err.println("获取最新消息:" + sny_webString);
        //这里已经获得了最新的消息,需要转存储到Jsob数组里面
        int new_msg_count = usjson.get("AddMsgCount").getAsInt();
        //大于0是有新消息
        if (new_msg_count > 0) {
            //执行消息处理
            SaveNewMsg(usjson.get("AddMsgList").getAsJsonArray());
        }
    }

    /**
     * 对新的消息进行记录进全局
     *
     * @param AddMsgList
     */
    private void SaveNewMsg(JsonArray AddMsgList) {

        int add_msg_num = 0;
        Iterator<JsonElement> iter = AddMsgList.iterator();
        while (iter.hasNext()) {
            JsonObject next = (JsonObject) iter.next();
            String msgid = next.get("MsgId").getAsString();
            //獲得消息時間戳
            int msg_create_time = next.get("CreateTime").getAsInt();
            //獲得消息 内容
            String msg_content = "";

            msg_content = HtmlUtils.htmlUnescape(next.get("Content").getAsString());

            //获得消息从哪里来的,由于自己永远是接收方,所以只记录from
            String from_username = next.get("FromUserName").getAsString();
            String who_msg = "friend";
            //如果发送人士自己,那么调整接收人为from
            if (AdminUserName.equals(from_username)) {
                from_username = next.get("ToUserName").getAsString();
                who_msg = "me";
            }
            //获得消息类型
            int msg_type = next.get("MsgType").getAsInt();

            //除了类型为1的文本3图片其他的全部不要
            if (msg_type != 1 && msg_type != 3) {
                //跳过以下的处理
                continue;
            }

            String image_string = "";
            //图片数据
            if (msg_type == 3) {
                msg_content = "[图片]";
                image_string = GetMsgImage(msgid);
            }

            //更新一下最近联系人,先删除老的 再加入新的
            AllLastCallFriends.remove(from_username);
            AllLastCallFriends.add(from_username);
            //刷新页面
            //如果界面当前选择的是最新消息栏目,则刷新
            FriendsPanel friend_panel = (FriendsPanel) AdminMain.AllPanels.get(WXCookies.get("wxuin").toString());
            if (friend_panel.SelectJLabel.getName().equals("last")) {
                ChangeShow.REShowSelectTypeFriends(WXCookies.get("wxuin").toString(), "last");
            }
//开始吧消息存储,按指定格式
            //每次执行,就账号新消息+1
            add_msg_num++;

            //如果消息里没有这个用户的字段,则创建一下
            if (!AllNewMsg.has(from_username)) {
                AllNewMsg.add(from_username, new JsonObject());
            }
            //这是要使用的用户的消息记录json
            JsonObject use_json = AllNewMsg.get(from_username).getAsJsonObject();
            //网里面新加一个
            JsonObject new_msg = new JsonObject();
            new_msg.addProperty("msg_content", msg_content);
            new_msg.addProperty("msg_time", msg_create_time);
            new_msg.addProperty("who", who_msg);
            new_msg.addProperty("msg_image", image_string);//保存图片的字符

            //按时间写出
            use_json.add("" + msg_create_time, new_msg);

            System.err.println("获得一个新消息:" + msg_content);
            //让消息显示在对应的朋友的名称下面(最后一条消息)
            ChangeShow.ChangeFriendMsgCountNum(WXCookies.get("wxuin").toString(), from_username, msg_content);

        }

        //这里得到了统计的微信账号的所有新消息统计数
        //刷新一次界面数量
        ChangeShow.ChangeAdminMsgCountNumber(WXCookies.get("wxuin").toString());
        //消息记录结束
        //播放声音
        ChangeShow.PlayWav();
    }

    /**
     * 关闭实例
     */
    public void Close() {
        ThreadStatus = false;//关闭值守线程
        HeartJumpThread = null;
    }

    /**
     * 组装Synckey
     *
     * @return
     */
    private String MakeSynckey() {
        String use_synkey = "";
        //循环

        JsonObject SyncKey = (JsonObject) MyInfo.get("SyncKey");
        JsonArray key_list = SyncKey.get("List").getAsJsonArray();

        for (Iterator iterator = key_list.iterator(); iterator.hasNext();) {
            JsonObject next = (JsonObject) iterator.next();

            String key = next.get("Key").toString();
            String value = next.get("Val").toString();
            use_synkey += key + "_" + value + "|";

        }

        String new_use_synkey = use_synkey.substring(0, use_synkey.length() - 1);
//        System.err.println(new_use_synkey);
        return new_use_synkey;

    }

    /**
     * 改变图片的大小并返回
     *
     * @param old_image
     * @param width
     * @param height
     * @return
     */
    public Image SetImageSize(Image old_image, int width, int height) {
        Image use_image = old_image.getScaledInstance(width, height, Image.SCALE_FAST);
        return use_image;
    }

    /**
     * 改变图片大小并返回
     *
     * @param old_image
     * @param width
     * @param height
     * @return
     */
    public Image SetImageSize(ImageIcon old_image, int width, int height) {
        Image new_image = old_image.getImage();
        Image use_image = new_image.getScaledInstance(width, height, Image.SCALE_FAST);
        return use_image;
    }

    /**
     * 把byte转指定大小的image
     *
     * @param b
     * @param width
     * @param height
     * @return
     */
    public Image SetImageSize(byte[] b, int width, int height) {
        Image new_image = new ImageIcon(b).getImage();
        Image use_image = new_image.getScaledInstance(width, height, Image.SCALE_FAST);
        return use_image;
    }

    /**
     * 把hashmap 转换成json 字符串
     *
     * @param jsonob
     * @return json 的string
     */
    public String HashToJsonString(JsonObject jsonob) {
        Gson gson = new Gson();
        String jsonstring = gson.toJson(jsonob);
//        System.err.println(jsonstring);
        return jsonstring;
    }

    /**
     * 发送消息给自己的好友
     *
     * @param FriendUserName 朋友用户名
     * @param MsgContent 消息内容
     * @return boolean 成功 时报
     */
    public boolean SendMsgToFriend(String FriendUserName, String MsgContent) {
        JsonObject use_info = (JsonObject) MyInfo.get("User");

        //要请求的页面
        String post_url = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket="
                + WXCookies.get("pass_ticket").toString() + "&lang=zh_CN";
        System.err.println("post_url=" + post_url);
        //要请求的数据
        //BaseRequest部分
        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", WXCookies.get("wxuin").toString());
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        String use_msgid = MakeMsgId();
        //msg部分
        JsonObject jsonmsg = new JsonObject();
        jsonmsg.addProperty("Type", 1);
        jsonmsg.addProperty("Content", MsgContent);
        jsonmsg.addProperty("FromUserName", use_info.get("UserName").getAsString());
        jsonmsg.addProperty("ToUserName", FriendUserName);
        jsonmsg.addProperty("LocalID", use_msgid);
        jsonmsg.addProperty("ClientMsgId", use_msgid);

        JsonObject new_json = new JsonObject();
        new_json.add("BaseRequest", jsonob);
        new_json.add("Msg", jsonmsg);
        new_json.addProperty("Scene", 0);

        //请求http
        RTHttp rhttp = new RTHttp(post_url);
        rhttp.SetCookies(rhttp.MakeCookies(WXCookies));
        String post_json_string = HashToJsonString(new_json);
        System.err.println("发消息请求参数:" + post_json_string);
        String result_back = rhttp.Post(post_json_string);
        rhttp.close();
        System.err.println(result_back);

        //检查消息结果
        Gson us_gson = new Gson();
        JsonObject us_json = us_gson.fromJson(result_back, JsonObject.class);
        JsonObject BaseResponse = us_json.getAsJsonObject("BaseResponse");
        String ret_text = BaseResponse.get("Ret").toString();
        if (ret_text.equals("0")) {
            //成功后把消息加入老消息记录里
            JsonObject add_to_old = new JsonObject();
            add_to_old.addProperty("msg_content", MsgContent);
            add_to_old.addProperty("who", "me");
            add_to_old.addProperty("msg_image", "");
            //读出所有词用户的老数据
            if (!AllOldMsg.has(FriendUserName)) {
                AllOldMsg.add(FriendUserName, new JsonObject());
            }
            JsonObject all_friend_msg = AllOldMsg.get(FriendUserName).getAsJsonObject();
            //加入这一条
            all_friend_msg.add("" + System.currentTimeMillis(), add_to_old);
            //再把记录寸回去
            AllOldMsg.add(FriendUserName, all_friend_msg);
            return true;
        } else {
            return false;
        }

    }

    /**
     * 生成时间戳加随机4位
     *
     * @return
     */
    private String MakeMsgId() {
        String time_1 = "" + System.currentTimeMillis();

//        System.err.println("1获得时间戳:" + time_1);
        //最后补上4位随机
        int rand_num = new Random().nextInt(99999);
        String rand_string = ("" + rand_num).substring(0, 4);

//        System.err.println("获得随机4位" + rand_string);
        String use_msgid = time_1.substring(0, 4);
//        System.err.println("组装前4位:" + use_msgid);
        use_msgid = use_msgid + rand_string;
//        System.err.println("加入随机数" + use_msgid);
        use_msgid = use_msgid + time_1.substring(4, time_1.length());
//        System.err.println("组装完毕:" + use_msgid);
        return use_msgid;
    }

    /**
     * 上传文件到微信服务器
     * <br>返回获得mediaid 用来发消息时候用
     *
     * @param file_path 文件路径
     * @param to_username 发送给那个用户
     * @return 返回上传成功的图片base64
     */
    public String UpdateMedia(String file_path, String to_username) {

        //获取准备上传的文件
        File UpLoadFile = new File(file_path);

        //先准备一个json 字符集
        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", Integer.parseInt(WXCookies.get("wxuin").toString()));
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        JsonObject use_json = new JsonObject();
        use_json.addProperty("UploadType", 2);
        use_json.add("BaseRequest", jsonob);
        use_json.addProperty("ClientMediaId", System.currentTimeMillis());
        use_json.addProperty("TotalLen", UpLoadFile.length());
        use_json.addProperty("StartPos", 0);
        use_json.addProperty("DataLen", UpLoadFile.length());
        use_json.addProperty("MediaType", 4);
        use_json.addProperty("FromUserName", AdminUserName);
        use_json.addProperty("ToUserName", to_username);
        use_json.addProperty("FileMd5", MD5Util.getFileMD5(UpLoadFile));

        String json_string = HashToJsonString(use_json);

        //调用一个独立的上传链接类
        WeXinUploadFile weixinup = new WeXinUploadFile(UpLoadFile, to_username, json_string, WXCookies);

        //获得上传图片后的返回结果
        String result_string = weixinup.SendUpFile();
        //解析json
        Gson gson = new Gson();
        JsonObject json = gson.fromJson(result_string, JsonObject.class);
        //获得需要的数据
        JsonObject BaseResponse = json.get("BaseResponse").getAsJsonObject();
        int ret = BaseResponse.get("Ret").getAsInt();
        String mediaid = json.get("MediaId").getAsString();
        if (ret != 0) {
            System.err.println("上传失败:ret=" + ret);
            return "";
        }

        //开始发送通知消息
        return BackPost(mediaid, to_username);
    }

    /**
     * 返回mediaid后再次提交请求
     *
     * @param midiaidString 媒体id
     * @param to_username 发送给谁
     */
    private String BackPost(String midiaidString, String to_username) {
        //组装数据
        //先准备一个json 字符集
        JsonObject jsonob = new JsonObject();
        jsonob.addProperty("Uin", Integer.parseInt(WXCookies.get("wxuin").toString()));
        jsonob.addProperty("Sid", WXCookies.get("wxsid").toString());
        jsonob.addProperty("Skey", WXCookies.get("skey").toString());
        jsonob.addProperty("DeviceID", MyInfo.get("DeviceID").toString());

        String timestamp = MakeMsgId();

        JsonObject jsonmsg = new JsonObject();
        jsonmsg.addProperty("Type", 3);
        jsonmsg.addProperty("MediaId", midiaidString);
        jsonmsg.addProperty("Content", "");
        jsonmsg.addProperty("FromUserName", AdminUserName);
        jsonmsg.addProperty("ToUserName", to_username);
        jsonmsg.addProperty("LocalID", timestamp);
        jsonmsg.addProperty("ClientMsgId", timestamp);

        JsonObject use_json = new JsonObject();
        use_json.add("BaseRequest", jsonob);
        use_json.add("Msg", jsonmsg);
        use_json.addProperty("Scene", 0);

        String json_string = HashToJsonString(use_json);
//        System.err.println("midiaid再次上传json字符串:" + json_string);
        String post_url = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsgimg?fun=async&f=json&pass_ticket="
                + WXCookies.get("pass_ticket").toString() + "&lang=zh_CN";
        RTHttp rhttp = new RTHttp(post_url);
        rhttp.SetCookies(rhttp.MakeCookies(WXCookies));
        String back = rhttp.Post(json_string);
        //解析json
        Gson gson = new Gson();
        JsonObject json = gson.fromJson(back, JsonObject.class);
        //获得需要的数据
        JsonObject BaseResponse = json.get("BaseResponse").getAsJsonObject();
        int ret = BaseResponse.get("Ret").getAsInt();
        if (ret != 0) {
            System.err.println("上传失败:ret=" + ret);
            return "";
        }
        //获得msgid
        String MsgId = json.get("MsgID").getAsString();

        //获得图片返回
        String back_image_string = GetMsgImage(MsgId);
        //成功后把消息加入老消息记录里
        JsonObject add_to_old = new JsonObject();
        add_to_old.addProperty("msg_content", "");
        add_to_old.addProperty("who", "me");
        add_to_old.addProperty("msg_image", back_image_string);
        //读出所有词用户的老数据
        if (!AllOldMsg.has(to_username)) {
            AllOldMsg.add(to_username, new JsonObject());
        }
        JsonObject all_friend_msg = AllOldMsg.get(to_username).getAsJsonObject();
        //加入这一条
        all_friend_msg.add("" + System.currentTimeMillis(), add_to_old);
        //再把记录寸回去
        AllOldMsg.add(to_username, all_friend_msg);

        return back_image_string;
    }

    /**
     * 根据msgid 取回 发送过来的图片
     *
     * @param msgid
     * @return 返回图片的byte
     */
    public String GetMsgImage(String msgid) {
        String back_string = "";
        byte[] get_image_byte = null;
        String get_url = "https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetmsgimg?"
                + "MsgID=" + msgid
                + "&skey=" + URLEncoder.encode(WXCookies.get("skey").toString()) + "&type=slave";
        System.err.println(get_url);
        RTHttp rhttp = new RTHttp(get_url);
        rhttp.SetCookies(rhttp.MakeCookies(WXCookies));
        get_image_byte = rhttp.GetImage();
        rhttp.close();

        if (get_image_byte != null) {
            back_string = Base64.getEncoder().encodeToString(get_image_byte);
            String FG = System.getProperty("file.separator");
            String file_path = "." + FG + "images" + FG + msgid + ".jpg";
//            ChangeShow.SaveImageToFile(file_path, get_image_byte);
        }
        return back_string;
    }

}
